using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Text;
using System.Xml.Serialization;

namespace PeDALS.Tools.AZ.PSTArchive.PSTData
{
    public static class DynProps
    {
        private static SortedList<UInt32, DynProperty> mslProps = new SortedList<uint,DynProperty>();
        private static bool mblnPropsLoaded;
        private static string mstrErrorString;

        static DynProps()
        {
            try
            {
                XmlSerializer xsSerializer = new XmlSerializer(typeof(IntProperty));
                StreamReader srReader = new StreamReader(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + "\\property.xml");
                IntProperty ipProperties = (IntProperty)xsSerializer.Deserialize(srReader);
                srReader.Close();
                foreach (DynProperty dpProperty in ipProperties.Property)
                {
                    mslProps.Add(Convert.ToUInt32(dpProperty.PropertyID) << 16 | Convert.ToUInt32(dpProperty.PropertyTypeID), dpProperty);
                }
                mblnPropsLoaded = true;
            }
            catch (Exception eException)
            {
                mstrErrorString = string.Format("{0}", eException.Message);
            }
        }

        public static SortedList<UInt32, DynProperty> Props
        {
            get { return mslProps; }
        }

        public static bool Loaded
        {
            get { return mblnPropsLoaded; }
        }

        public static string Error
        {
            get { return mstrErrorString; }
        }
    }

    [XmlRoot(ElementName = "dataroot")]// Namespace = "http://www.pedalspreservation.org", xmlns="http://www.pedalspreservation.org"
    public class IntProperty
    {
        private List<DynProperty> madpProperties;

        public IntProperty()
        {
        }

        [XmlElement]
        public List<DynProperty> Property
        {
            get { return madpProperties; }
            set { madpProperties = value; }
        }
    }

    //[XmlRoot(ElementName = "Property")][XmlRoot(Namespace = "http://www.pedalspreservation.org")]
    public class DynProperty
    {
        private UInt16 mu16PropertyID;
        private UInt16 mu16PropertyTypeID;
        private string mstrDisplayName;
        private string mstrTagName;
        private string mstrDescription;
        private string mstrReference;

        public DynProperty()
        {
        }

        public DynProperty(UInt16 u16PropertyID, UInt16 u16PropertyTypeID, string strDisplayName, string strTagName, string strDescription, string strReference)
        {
            mu16PropertyID = u16PropertyID;
            mu16PropertyTypeID = u16PropertyTypeID;
            mstrDisplayName = strDisplayName;
            mstrTagName = strTagName;
            mstrDescription = strDescription;
            mstrReference = strReference;
        }

        [XmlIgnore]
        public UInt16 PropertyID
        {
            
            get { return mu16PropertyID; }
            set { mu16PropertyID = value; }
        }

        [XmlElement("PropertyID")]
        public string PropertyIDString
        {

            get { return mu16PropertyID.ToString("X4"); }
            set { mu16PropertyID = UInt16.Parse(value, System.Globalization.NumberStyles.HexNumber); }
        }

        [XmlIgnore]
        public UInt16 PropertyTypeID
        {
            get { return mu16PropertyTypeID; }
            set { mu16PropertyTypeID = value; }
        }

        [XmlElement("PropertyTypeID")]
        public string PropertyTypeIDString
        {
            get { return mu16PropertyTypeID.ToString("X4"); }
            set { mu16PropertyTypeID = UInt16.Parse(value, System.Globalization.NumberStyles.HexNumber); }
        }

        public string DisplayName
        {
            get { return mstrDisplayName; }
            set { mstrDisplayName = value; }
        }

        public string TagName
        {
            get { return mstrTagName; }
            set { mstrTagName = value; }
        }

        public string Description
        {
            get { return mstrDescription; }
            set { mstrDescription = value; }
        }

        public string Reference
        {
            get { return mstrReference; }
            set { mstrReference = value; }
        }
    }
    
    public enum NIDTypes : byte 
    {
        HeapNode = 0x00,
        InternalNode = 0x01,
        NormalFolder = 0x02,
        SearchFolder = 0x03,
        NormalMessage = 0x04,
        Attachment = 0x05,
        SearchUpdateQueue = 0x06,
        SearchCriteriaObject = 0x07,
        AssociatedMessageFAI = 0x08,
        ContentsTableIndex = 0x0A,
        InboxReceiveFolderTable = 0x0B,
        OutboxQueue = 0x0C,
        HierarchyTable = 0x0D,
        ContentsTable = 0x0E,
        AssociatedContentsTableFAI = 0x0F,
        SearchContentsTable = 0x10,
        AttachmentTable = 0x11,
        RecipientTable = 0x12,
        SearchTableIndex = 0x13,
        LTP = 0x1F
    }

    public enum EncryptionTypes : byte
    {
        None = 0x00,
        Permute = 0x01,
        Cyclic = 0x02
    }

    public enum PageTypes : byte
    {
        BlockBTree = 0x80,
        NodeBTree = 0x81,
        FreeMap = 0x82,
        PageMap = 0x83,
        AllocationMap = 0x84,
        FreePageMap = 0x85,
        DensityList = 0x86
    }

    public enum ContextType : byte
    {
        Table = 0x7C,
        Property = 0xBC
    }
}